/*	Date:2017/7/29
 *	Author: Chunsheng Chen
 *	功能： 提供类型、以及类型+值的构造。
 */

#ifndef _C_TYPE_H
#define _C_TYPE_H

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"util.h"
#include"symbol.h"

/*
结构名： type
成员： kind -> 指明类型（int|char|double|array|struct|void）
		u -> 联合体，包含对各种不同类型的信息扩展
功能：记录标识符的类型，帮助实现 symbol -> type 的类型符号表
 */
struct type{
	enum { 		var_int = 100,
				var_char,
				var_double,
				var_array,
				var_struct,
				var_void
							} kind;
	
	union{
		/**/
		struct type* arr;	//如果是数组类型，还需要登记它的类型,此外还应该知道数组的大小。之后会修改回来
		
		struct field{ //辅助fieldlist使用的结构体，表示结构体中每个域的名字还有类型
			struct symbol* sym;
			struct type* fieldtype;
		};
		/**/
		struct fieldlist{//如果是结构体，则需要记录每个域名的名字还有类型，暂时用的是链表。可以考虑别的数据结构(例如二叉树之类的)
						struct field* f;	// field
						struct fieldlist* next;
		}*list;
	}u;
};

/*
结构名： valtype
成员： ty -> 指明类型
		u -> 联合体，包含对各种不同类型的具体的值
功能：记录标识符的值，帮助实现 symbol -> 值 的值符号表
 */

struct valtype{
	struct type* ty;
	union{
		int i;	//类型是 int,
		double d;//类型是 double,
		char c; // 类型是 char
		struct valarr{
			int size;//如果是数组，应该知道其大小
			struct valtype* val;
		}*arr;
		struct valfield{//帮助实现对结构体成员的值的赋。
						//表示 具体的 符号以及对应的 valtype 值。
			struct symbol* sym;
			struct valtype* ft;
		};

		struct valfieldlist{ // 类型是结构体
			struct valfield* vf;
			struct valfieldlist* next;
		}*list;
	}u;
};

struct valtypeList{
	struct valtype* val;
	struct valtypeList*  next;
};

/*
结构名： typeList
功能： 用于函数的参数列表，不过貌似短暂来说没有太大作用。声明定义分开才会用到它
*/
struct typeList{
	struct type* head;
	struct typeList* next;
};

//返回内置的 int类型的 type* 指针
struct type* cm_ty_tyint();

//返回内置的 double类型的 type* 指针
struct type* cm_ty_tydouble();

//返回内置的 char类型的 type* 指针
struct type* cm_ty_tychar();

//返回内置的 void类型的 type* 指针
struct type* cm_ty_tyvoid();

//构造结构体类型 @1 域链
struct type* cm_Struct(struct fieldlist*);

//构造数组类型 @1 数组的类型
struct type* cm_Array(struct type*);

//构造 typelist 类型
struct typeList* cm_typeList(struct type*, struct typeList*);

struct valtypeList* cm_valtypeList(struct valtype*, struct valtypeList*);

//构造 域
struct field* cm_Field(struct symbol*, struct type*);

//构造域链
struct fieldlist* cm_FieldList(struct field*, struct fieldlist*);

//构造一个新的变量 @1类型
struct valtype* cm_valtype(struct type*);



struct valtype* cm_valarray(struct type*, int);

//构造 域链以及以及对应的值
struct valfieldlist* cm_valfieldlist(struct field*, struct valfieldlist*);

//内置的 加操作，两个变量之间的加法
struct valtype* plus_val(struct valtype*, struct valtype*);

//内置的 减操作，两个变量之间的加法
struct valtype* minus_val(struct valtype*, struct valtype*);

//内置的 乘操作，两个变量之间的加法
struct valtype* mul_val(struct valtype*, struct valtype*);

//内置的 除操作，两个变量之间的加法
struct valtype* div_val(struct valtype*, struct valtype*);

//小于
struct valtype* val_cmp_Less(struct valtype*, struct valtype*);

//小于等于
struct valtype* val_cmp_LessOrEqual(struct valtype*, struct valtype*);

//等于
struct valtype* val_cmp_Equal(struct valtype*, struct valtype*);

//大于
struct valtype* val_cmp_Greater(struct valtype*, struct valtype*);

//大于等于
struct valtype* val_cmp_GreaterOrEqual(struct valtype*, struct valtype*);

//不等于
struct valtype* val_cmp_NotEqual(struct valtype*, struct valtype*);


//内置的 赋值操作，将 @2 赋值给 @1
void assign_val(struct valtype*, struct valtype*);

//获取变量的对应的值，并且转化成别的内置类型
int toInt(struct valtype*);

double toDouble(struct valtype*);

char toChar(struct valtype*);

//显示变量的值
void showValue(struct valtype*);

//辅助showValue函数，显示结构体中各个域的值
void showfieldvalue(struct valfield*);

//对于常数而言，先将他们转化为对应的临时变量，再进行操作
struct valtype* convertInt(int);

struct valtype* convertDouble(double);

struct valtype* convertChar(char);

struct valtype* get_StructField(struct valtype*, struct symbol*);

#endif
